package ru.sushka.lunch.dao.psql;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import ru.sushka.lunch.dao.AbstractDao;
import ru.sushka.lunch.enitiy.Persistentce;

public abstract class PsqlDao<T extends Persistentce> implements AbstractDao<T> {
    
    protected abstract String getTableName();
    protected abstract String getSelectSqlQuery(int id);
    protected abstract String getDeleteSqlQuery(int id);
    protected abstract String getInsertSqlQuery(T persistent);
    protected abstract String getUpdateSqlQuery(T persistent);
    
    protected abstract T parseResultSet(ResultSet rs) throws SQLException;
    
    @Override
    public T get(int id) {     
        PreparedStatement st = null;
        ResultSet rs = null;
        String query=getSelectSqlQuery(id);
        System.out.println(query);
        try {
            st = createQuery(query);
            rs = st.executeQuery();
            if(rs.next()){
                T persistent = parseResultSet(rs);
                return persistent;
            }          
        } catch (Exception e) {
            
            e.printStackTrace();
        } finally {
            try {
                if (st != null)
                    st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        throw new RuntimeException("");
    }

    @Override
    public List<T> getList(String filter) {     
        PreparedStatement st = null;
        ResultSet rs = null;
        List<T> resultList = new ArrayList<T>();
        String query="select * from "+getTableName() + (filter.trim().equals("") ? "" : " and " + filter);
        System.out.println(query);
        try {
            st = createQuery(query);
            rs = st.executeQuery();
            while(rs.next()){
                T persistent = parseResultSet(rs);
                resultList.add(persistent);
            }    
            return resultList;
        } catch (Exception e) {
            
            e.printStackTrace();
        } finally {
            try {
                if (st != null)
                    st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        throw new RuntimeException("");
    }

    @Override
    public int getCount() {  
        PreparedStatement st = null;
        ResultSet rs = null;
        String query="SELECT Max(id) FROM "+getTableName();
        System.out.println(query);
        try {
            st = createQuery(query);
            rs = st.executeQuery();
            if(rs.next()){
                return rs.getInt(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("");
        } finally {
            try {
                if (st != null)
                    st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        throw new RuntimeException("");
    }

    @Override
    public void insert(T persistent) {      
        PreparedStatement st = null;
        String query=getInsertSqlQuery(persistent);
        System.out.println(query);
        try {
            st = createQuery(query);
            st.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("");
        } finally {
            try {
                if (st != null)
                    st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void delete(T persistent) {        
        PreparedStatement st = null;
        String query=getDeleteSqlQuery(persistent.getId());
        System.out.println(query);
        try {
            st = createQuery(query);
            st.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("");
        } finally {
            try {
                if (st != null)
                    st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }  
    }

    @Override
    public void update(T persistent) {       
        PreparedStatement st = null;
        String query=getUpdateSqlQuery(persistent);
        System.out.println(query);
        try {
            st = createQuery(query);
            st.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("");
        } finally {
            try {
                if (st != null)
                    st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }   
    }

    private PreparedStatement createQuery(String sql) throws SQLException{
        return ConnectionManager.getInstance().getConnection().prepareStatement(sql);
    }
    

    
}
